//    This file is part of Open WordSearch.
//
//    Open WordSearch is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Open WordSearch is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Open WordSearch.  If not, see <http://www.gnu.org/licenses/>.
//
//        Copyright 2009, 2010 Brendan Dahl <dahl.brendan@brendandahl.com>
//              http://www.brendandahl.com

package com.abhipedro.wordsearch.view.controller;

import java.util.Calendar;
import java.util.LinkedList;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Vibrator;
import android.widget.ImageButton;
import android.widget.TextView;

import com.abhipedro.wordsearch.model.Grid;
import com.abhipedro.wordsearch.model.HighScore;
import com.abhipedro.wordsearch.model.Preferences;
import com.abhipedro.wordsearch.model.dictionary.DictionaryManager;
import com.abhipedro.wordsearch.util.Constants;
import com.abhipedro.wordsearch.view.R;
import com.abhipedro.wordsearch.view.SettingsActivity;
import com.abhipedro.wordsearch.view.WordSearchActivity;
import com.abhipedro.wordsearch.view.runnables.CongradulationToast;
import com.abhipedro.wordsearch.view.runnables.HighScoresInitials;

/**
 * controls game logic and sub-control modules for word search activity
 */
public class WordSearchActivityController {
	/**
	 * this is the size of the current grid, also used by convertionUtil
	 */
	private static int gridSize = -1;
	private WordBoxController wordBoxManager;
	private TextViewGridController gridManager;
	private DictionaryManager dictionaryFactory;
	private long timeStart = 0L;
	private long timeSum = 0L;
	private Grid grid;
	final private Preferences prefs;
	private WordSearchActivity wordSearch;

	/**
	 * used to serialize the control to and from a bundle
	 */
	private static final String BUNDLE_TIME = "ws_time";
	private static final String BUNDLE_VIEW = "ws_view";
	private static final String BUNDLE_GRID = "ws_grid";
	private static final String BUNDLE_GRID_SIZE = "ws_grid_size";

	private Vibrator mVibrator;
	private boolean mVibrate;

	public static int getGridSize() {
		return gridSize;
	}

	public WordSearchActivityController(WordSearchActivity wordSearch) {
		super();
		this.wordSearch = wordSearch;
		prefs = new Preferences(this.wordSearch);
		
		mVibrate = SettingsActivity.getVibration(wordSearch) ? true : false;
		mVibrator = (Vibrator) wordSearch.getSystemService(Context.VIBRATOR_SERVICE);
		
		TextView wordBox = (TextView) wordSearch.findViewById(R.id.wordBox);
		ImageButton prev = (ImageButton) wordSearch.findViewById(R.id.prev);
		ImageButton next = (ImageButton) wordSearch.findViewById(R.id.next);
		wordBoxManager = new WordBoxController(prev, next, wordBox, null);
		
		ColorStateList normal;
		ColorStateList picked = wordSearch.getResources().getColorStateList(
				R.drawable.color_picked);
		ColorStateList found;
		
		int themeVal = Integer.valueOf(SettingsActivity.getTheme(wordSearch));
		switch (themeVal) {
		case 1:
			normal = wordSearch.getResources().getColorStateList(
					R.drawable.color_letter_white);
			found = wordSearch.getResources().getColorStateList(
					R.drawable.color_found_green);
			break;
		case 2:
		case 3:
			normal = wordSearch.getResources().getColorStateList(
					R.drawable.color_standard);
			found = wordSearch.getResources().getColorStateList(
					R.drawable.color_found);
			break;
		case 4:
			normal = wordSearch.getResources().getColorStateList(
					R.drawable.color_letter_white);
			found = wordSearch.getResources().getColorStateList(
					R.drawable.color_found);
			break;
		case 7:
			normal = wordSearch.getResources().getColorStateList(
					R.drawable.color_letter_white);
			found = wordSearch.getResources().getColorStateList(
					R.drawable.color_found);
			break;
		default:
			normal = wordSearch.getResources().getColorStateList(
					R.drawable.color_standard);
			found = wordSearch.getResources().getColorStateList(
					R.drawable.color_found);
			break;
		}

		gridManager = new TextViewGridController(this, new TextView[prefs
				.getSize()][], found, picked, normal, wordSearch);

	}

	protected void foundWord(String word) {
		int remainingWordCount = wordBoxManager.wordFound(word);
		
		wordSearch.updateLeftWordsCount(remainingWordCount);

		if (mVibrate)
			mVibrator.vibrate(300);

		if (remainingWordCount == 0) {
			// game end
			Calendar diffTime = Calendar.getInstance();
			Long diffMill = System.currentTimeMillis() - timeStart + timeSum;
			diffTime.setTimeInMillis(diffMill);
			setHighScore(diffMill);
		}
	}

	public TextViewGridController getGridManager() {
		return gridManager;
	}

	public LinkedList<HighScore> getHighScores() {
		return prefs.getTopScores();
	}

	public Preferences getPrefs() {
		return prefs;
	}


	public String guessWord(Point pointStart, Point pointEnd) {
		return grid.guessWord(pointStart, pointEnd);
	}

	public void newWordSearch() {
		this.setGridSize(prefs.getSize());
		
		dictionaryFactory = new DictionaryManager(this.wordSearch);

		grid = Grid.generateGrid(dictionaryFactory, getGridSize());

		timeSum = 0L;
		this.setGrid(grid);
		
		wordSearch.updateLeftWordsCount(grid.getWordListLength());
		
	}

	/**
	 * Made by Pedro. Returns the Current Game word list as a Text, that is the
	 * varios words separeted by \n
	 * 
	 * @return
	 */
	public String getWordList() {
		LinkedList<String> lista = new LinkedList<String>(grid.getWordList());
		int tam = lista.size();
		int i = 1;
		String resultado = lista.getFirst();
		while (i < tam) {
			resultado = resultado + "\n" + lista.get(i);
			i++;
		}
		return resultado;
	}

	public void resetScores() {
		prefs.resetTopScores();
	}

	public void restoreState(Bundle inState) {
		if (inState != null) {
			this.timeSum = inState.getLong(BUNDLE_TIME, 0);
			this.grid = inState.getParcelable(BUNDLE_GRID);
			this.setGrid(grid);
			this.gridManager.fromBundle(inState.getBundle(BUNDLE_VIEW));
		}
	}

	public void saveState(Bundle outState) {
		if (outState != null) {
			outState.putInt(BUNDLE_GRID_SIZE, gridSize);
			outState.putLong(BUNDLE_TIME, this.timeSum);
			outState.putParcelable(BUNDLE_GRID, this.grid);
			outState.putBundle(BUNDLE_VIEW, this.gridManager.toBundle());
		}
	}

	private void setGrid(Grid grid) {
		gridManager.reset(grid);
		wordBoxManager.resetWords(grid.getWordList());
		timeStart = System.currentTimeMillis();
	}

	public void setGridSize(int gridSizeNew) {
		gridSize = prefs.getSize();
		gridManager.setGridView(new TextView[gridSize][]);
		wordSearch.setupViewGrid(gridSize, gridManager);
	}

	private boolean setHighScore(long time) {
		boolean highScorer = false;
		HighScore hs = new HighScore(time, gridSize,( 90 / 100));
		LinkedList<HighScore> scores = prefs.getTopScores();

		int lastIndex = 1;
		if (scores.size() > 1)
			lastIndex = scores.size() > Constants.MAX_HIGH_SCORES ? Constants.MAX_HIGH_SCORES
					: scores.size() - 1;
		if (scores.size() < Constants.MAX_HIGH_SCORES
				|| hs.getScore() > scores.get(lastIndex - 1).getScore()) {
			wordSearch.runOnUiThread(new HighScoresInitials(this, hs,
					wordSearch, prefs));
		} else {
			wordSearch.runOnUiThread(new CongradulationToast(this, hs, wordSearch));
		}
		return highScorer;
	}


	public long getElapsed() {
		return timeSum;
	}

	public void timePause() {
		timeSum += System.currentTimeMillis() - timeStart;
	}

	public void timeResume() {
		timeStart = System.currentTimeMillis();
	}

}
